﻿using Elsa.Models;
using SqlSugar.Extensions;
using Zhp.SqlSugar.Repository;
using Zhp.Workflow.Activities.DataOptions;
using Zhp.Workflow.Entity;
using Zhp.Workflow.Entity.DataOptions;
using Zhp.Workflow.Models;

namespace Zhp.Workflow.Notify.Services
{
    public class TodoService : ITodoService
    {
        private readonly IBaseRepository<WorkflowTodo> _rep;
        private readonly IBaseRepository<SysUserRole> _userRoleRep;
        public TodoService(IBaseRepository<WorkflowTodo> rep, IBaseRepository<SysUserRole> userRoleRep)
        {
            _rep = rep;
            _userRoleRep = userRoleRep;
        }

        public async Task InsertTodo(WorkflowInstance wf, WorkflowStatusEnum workflowStatus)
        {
            var submiterId = wf.Variables.Get<string>(WorkflowVariables.SubmiterId);
            var submiterName = wf.Variables.Get<string>(WorkflowVariables.SubmiterName);

            // 流程到审批节点会先被挂起，然后通知审批人去审批
            var todoList = new List<WorkflowTodo>();
            var nextNodeList = QueryNextApproverList(wf);
            var roleIdList = nextNodeList.Where(x => x.ApproverRole == ApproverRoleEnum.Role).Select(x => x.ApproverId).ToList();
            var userRoleList = await _userRoleRep.GetListAsync(x => roleIdList.Contains(x.RoleId));
            var userRoleDict = userRoleList.GroupBy(x => new { x.RoleId }).ToDictionary(x => x.Key.RoleId, y => y.ToList());
            foreach (var item in nextNodeList)
            {
                if (item.ApproverRole == ApproverRoleEnum.User)
                {
                    todoList.Add(new WorkflowTodo
                    {
                        ApproverId = item.ApproverId,
                        ApproverRole = item.ApproverRole,
                        WorkflowName = wf.Name,
                        WorkflowId = wf.Id,
                        ActivityId = item.ActivityId,
                        ModelType = wf.ContextType,
                        ModelID = wf.ContextId,
                        SubmitterName = submiterName,
                        SubmitterId = submiterId,
                        WorkflowStatus = workflowStatus,
                        IsSend = false
                    });
                }
                else if (item.ApproverRole == ApproverRoleEnum.Role)
                {
                    if (userRoleDict.TryGetValue(item.ApproverId, out var sysUserRoles))
                    {
                        foreach (var ur in sysUserRoles)
                        {
                            todoList.Add(new WorkflowTodo
                            {
                                ApproverId = ur.UserId,
                                ApproverRole = item.ApproverRole,
                                WorkflowName = wf.Name,
                                WorkflowId = wf.Id,
                                ActivityId = item.ActivityId,
                                ModelType = wf.ContextType,
                                ModelID = wf.ContextId,
                                SubmitterName = submiterName,
                                SubmitterId = submiterId,
                                WorkflowStatus = workflowStatus,
                                IsSend = false
                            });
                        }
                    }
                }
            }
            await _rep.InsertRangeAsync(todoList);
        }

        private List<ApproverInfo> QueryNextApproverList(WorkflowInstance wf)
        {
            var nextNodeList = new List<ApproverInfo>();
            var activityIds = wf.BlockingActivities.Select(x => x.ActivityId).ToList();
            foreach (var activityId in activityIds)
            {
                var activityData = wf.ActivityData[activityId];
                if (activityData != null && activityData.TryGetValue("IsSendNotify", out object IsSendNotifyUser))
                {
                    if (IsSendNotifyUser != null && IsSendNotifyUser.ObjToBool())
                    {
                        if (activityData.TryGetValue("ApproveUsers", out object userIds))
                        {
                            if (userIds != null)
                            {
                                var userIdList = (userIds as IEnumerable<string>).Select(x => new ApproverInfo { ApproverRole = ApproverRoleEnum.User, ApproverId = Convert.ToInt64(x), ActivityId = activityId });
                                nextNodeList.AddRange(userIdList);
                            }
                        }
                    }
                }
                if (activityData != null && activityData.TryGetValue("IsSendNotify", out object IsSendNotifyRole))
                {
                    if (IsSendNotifyRole != null && IsSendNotifyRole.ObjToBool())
                    {
                        if (activityData.TryGetValue("ApproveRoles", out object roleIds))
                        {
                            if (roleIds != null)
                            {
                                var roleIdList = (roleIds as IEnumerable<string>).Select(x => new ApproverInfo { ApproverRole = ApproverRoleEnum.Role, ApproverId = Convert.ToInt64(x), ActivityId = activityId });
                                nextNodeList.AddRange(roleIdList);
                            }
                        }
                    }
                }
            }
            return nextNodeList;
        }
    }
}
